package com.campus.counseling.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.counseling.entity.PaymentRecord;
import com.campus.counseling.model.dto.DistributeIncomeDTO;
import com.campus.counseling.model.vo.PaymentRecordVO;
import com.campus.counseling.model.dto.RefundFormDTO;

import com.campus.counseling.service.PaymentService;
import com.campus.counseling.model.common.Result;
import com.campus.counseling.service.AlipayHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import org.springframework.security.access.prepost.PreAuthorize;


@Api(tags = "支付管理")
@RestController
@RequestMapping("api/payment")
@RequiredArgsConstructor
@CrossOrigin
public class PaymentController {

    private final PaymentService paymentService;
    private final AlipayHelper alipayHelper;
    private static final Logger log = LoggerFactory.getLogger(PaymentController.class);

    @ApiOperation("创建支付订单")
    @PostMapping("/create")
    public Result<String> createPayment(@RequestBody String appointmentInfo) {
        try {
            log.info("开始创建支付订单，appointmentInfo: {}", appointmentInfo);
            String form = paymentService.createPayment(appointmentInfo);
            log.info("创建支付订单成功");
            return Result.success(form);
        } catch (Exception e) {
            log.error("创建支付订单失败", e);
            return Result.error("创建支付订单失败：" + e.getMessage());
        }
    }

    @ApiOperation("支付回调")
    @PostMapping("/notify")
    public String paymentNotify(HttpServletRequest request) {
        try {
            // 获取所有请求参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            log.info("收到支付宝异步通知参数：{}", params);
            
            // 验证签名
            if (!alipayHelper.verifyNotify(params)) {
                log.error("支付宝异步通知验签失败");
                return "fail";
            }

            // 处理支付结果
            paymentService.handlePaymentNotify(params);
            return "success";
        } catch (Exception e) {
            log.error("处理支付宝异步通知失败", e);
            return "fail";
        }
    }

    @ApiOperation("支付返回")
    @GetMapping("/return")
    public void paymentReturn(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            // 获取所有请求参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            log.info("支付宝同步返回参数：{}", params);
            
            // 验证签名
            if (!alipayHelper.verifyNotify(params)) {
                log.error("支付宝同步返回验签失败");
                // 直接返回关闭页面的HTML
                returnClosePageResponse(response);
                return;
            }

            String tradeStatus = params.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                paymentService.handlePaymentReturn(params);
            } else {
                log.error("支付未成功，trade_status={}", tradeStatus);
            }
            
            // 无论支付成功还是失败，都返回关闭页面的HTML
            returnClosePageResponse(response);
            
        } catch (Exception e) {
            log.error("处理支付返回失败", e);
            // 发生异常时也返回关闭页面的HTML
            returnClosePageResponse(response);
        }
    }

    /**
     * 返回自动关闭的HTML页面
     */
    private void returnClosePageResponse(HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        String html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>处理中</title></head>" +
                     "<body><script>window.onload = function() { window.close(); };</script>" +
                     "<div style=\"text-align:center;margin-top:50px;\">支付处理完成，页面即将关闭...</div></body></html>";
        response.getWriter().write(html);
    }

    @ApiOperation("申请退款")
    @PostMapping("/refund")
    public Result<Void> refund(@RequestBody RefundFormDTO refundFormDTO) {
        try {
            log.info("收到退款申请：{}", refundFormDTO);
            paymentService.refund(refundFormDTO);
            return Result.success();
        } catch (Exception e) {
            log.error("退款申请失败", e);
            return Result.error("退款申请失败：" + e.getMessage());
        }
    }

    @ApiOperation("获取支付记录列表")
    @GetMapping("/list")
    public Result<Page<PaymentRecordVO>> getPaymentList(
        @RequestParam(defaultValue = "1") Integer pageNum,
        @RequestParam(defaultValue = "10") Integer pageSize,
        @RequestParam(required = false) String orderNo,
        @RequestParam(required = false) String status) {
        
        return Result.success(paymentService.getPaymentPage(pageNum, pageSize, orderNo, status));
    }

    @ApiOperation("获取支付记录详情")
    @GetMapping("/{orderNo}")
    public Result<PaymentRecord> getPaymentDetail(@PathVariable String orderNo) {
        return Result.success(paymentService.getByOrderNo(orderNo));
    }

    @ApiOperation("获取学生支付记录")
    @GetMapping("/student")
    public Result<Page<PaymentRecord>> getStudentPayments(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        return Result.success(paymentService.getStudentPayments(pageNum, pageSize));
    }

    @ApiOperation("获取咨询师收款记录")
    @GetMapping("/counselor")
    public Result<Page<PaymentRecordVO>> getCounselorPayments(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        return Result.success(paymentService.getCounselorPayments(pageNum, pageSize));
    }

    @ApiOperation("商品状态变更通知")
    @PostMapping("/item-notify")
    public String itemStatusNotify(@RequestParam Map<String, String> params) {
        try {
            log.info("收到商品状态变更通知：{}", params);
            return "success";
        } catch (Exception e) {
            log.error("处理商品状态变更通知失败", e);
            return "fail";
        }
    }

    @ApiOperation("交易结果通知")
    @PostMapping("/trade-notify")
    public String tradeStatusNotify(@RequestParam Map<String, String> params) {
        try {
            log.info("收到交易结果通知：{}", params);
            paymentService.handlePaymentNotify(params);
            return "success";
        } catch (Exception e) {
            log.error("处理交易结果通知失败", e);
            return "fail";
        }
    }

    @ApiOperation("订单状态变更通知")
    @PostMapping("/order-notify")
    public String orderStatusNotify(@RequestParam Map<String, String> params) {
        try {
            log.info("收到订单状态变更通知：{}", params);
            // 处理订单状态变更
            String orderNo = params.get("out_trade_no");
            String status = params.get("status");
            log.info("订单{}状态变更为：{}", orderNo, status);
            return "success";
        } catch (Exception e) {
            log.error("处理订单状态变更通知失败", e);
            return "fail";
        }
    }

    @GetMapping("/test-notify")
    public String testNotify() {
        log.info("测试通知地址可访问性");
        return "success";
    }

    @GetMapping("/income/list")
    @ApiOperation("获取收入列表")
    public Result<Page<PaymentRecordVO>> getIncomeList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String orderNo,
            @RequestParam(required = false) String counselorName,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        return Result.success(paymentService.getIncomeList(pageNum, pageSize, orderNo, counselorName, status, startDate, endDate));
    }

    @GetMapping("/income/statistics")
    @ApiOperation("获取收入统计")
    public Result<Map<String, Object>> getIncomeStatistics() {
        return Result.success(paymentService.getIncomeStatistics());
    }

    @PostMapping("/income/distribute")
    @ApiOperation("分发收入")
    public Result<Void> distributeIncome(@RequestBody DistributeIncomeDTO dto) {
        paymentService.distributeIncome(dto);
        return Result.success();
    }

    @GetMapping("/status/{orderNo}")
    @ApiOperation("获取支付状态")
    public Result<String> getPaymentStatus(@PathVariable String orderNo) {
        String status = paymentService.getPaymentStatus(orderNo);
        return Result.success(status);
    }

    @ApiOperation("审核退款申请")
    @PostMapping("/refund/approve")
    @PreAuthorize("hasAnyRole('admin', 'superadmin')")
    public Result<Void> approveRefund(
        @RequestParam String orderNo,
        @RequestParam boolean approved,
        @RequestParam(required = false) String remark
    ) {
        try {
            paymentService.approveRefund(orderNo, approved, remark);
            return Result.success();
        } catch (Exception e) {
            log.error("处理退款申请失败", e);
            return Result.error("处理退款申请失败：" + e.getMessage());
        }
    }

    @ApiOperation("取消订单")
    @PutMapping("/cancel/{orderNo}")
    public Result<Void> cancelPayment(@PathVariable String orderNo) {
        try {
            paymentService.cancelPayment(orderNo);
            return Result.success();
        } catch (Exception e) {
            log.error("取消订单失败", e);
            return Result.error("取消订单失败：" + e.getMessage());
        }
    }
} 